package com.redis.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Transaction;

import java.util.List;

/**
 * redis秒杀
 *
 * @Author:ChenZhangKun
 * @Date: 2021/8/17 16:59
 */
@Configuration
public class SeckillUtil {
    @Autowired
    private JedisPool jedisPool;

    public boolean soSecKill(String uid, String prodid) {
        Jedis jedis = jedisPool.getResource();
        // 非空判断
        if (uid == null || prodid == null) {
            return false;
        }
        // 凭借key
        // 库存key
        String kcKey = "sk:" + prodid + ":qt";
        // 用户key
        String userKey = "sk:" + prodid + ":user";
        // 监视库存
        // 在执行multi之前，先执行watch key1 [key2],可以监视一个(或多个) key ，
        // 如果在事务执行之前这个(或这些) key 被其他命令所改动，那么事务将被打断 基于乐观锁的机制
        jedis.watch(kcKey);
        // 库存
        Object kc = jedis.get(kcKey);
        if (kc == null) {
            System.out.println("秒杀尚未开始");
            jedis.close();
            return false;
        }
        // 判断用户是否重复秒杀
        Boolean b = jedis.sismember(userKey, uid);
        if (b) {
            System.out.println("用户已经秒杀成功，不能重复参与");
            jedis.close();
            return false;
        }
        // 判断库存
        if (Integer.parseInt(kc + "") <= 0) {
            System.out.println("秒杀结束");
            jedis.close();
            return false;
        }
        // 开启事务支持
        // 使用事务->z组队阶段
        Transaction transaction = jedis.multi();
        // 组队操作
        // 秒杀库存减一
        transaction.decr(kcKey);
        // 用户加入set集合
        transaction.sadd(userKey, uid);
        // 执行->执行阶段
        List result = transaction.exec();
        if (result == null || result.size() == 0) {
            System.out.println("秒杀失败了");
            jedis.close();
            return false;
        }
        jedis.close();
        return true;
    }
}
